const schedule = require('node-schedule');
const sendRequest = require('../../util/sendRequest.js');
const signAlgo = require('../../util/signAlgo.js');
const logger = require(`${global.rootPath}/util/logInit.js`).createLogger("timerS");
const config = require(`${global.rootPath}/config/${process.env.CONFIG}`);
const moment = require('moment');
const redisClient = require(`${global.rootPath}/util/cache`);
var timerObj = {};
var timerNum = 0;

const set = async (uuid,param) =>{
    let j = schedule.scheduleJob(param.trigger_time,async ()=>{
        logger.info(`[${uuid}]定时器执行开始`);
        //回调
        let data = JSON.parse(param.data);
        data['create_time'] = moment().format('YYYY-MM-DD HH:mm:ss');
        data['sign'] = signAlgo.sign(data,config.secret);
        await send_post(uuid,param.notify_url,data);
        logger.info(`[${uuid}]定时器执行结束`);
    })
    if(param.type != 1){
        //存储redis
        let process_id = process.env.NODE_APP_INSTANCE;
        let key = config.redis_key+"_"+process_id;
        await redisClient.hsetAsync(key,uuid,JSON.stringify(param));
        timerObj[uuid] = j;
        timerNum++;
    }
    return {
        msg: '请求成功',
        data: {
            id:uuid
        }
    }
}



/**
 * 返回了success之后也不会进行发送，否则会进行重发，最多5次
 * @param {*} url 
 * @param {*} param 
 * @param {*} time 第一次0s，第二次20s，第三次40s，第四次80s，第五次160s,五次之后不会进行发送
 */
async function send_post(uuid,url,param,timeout = 0,num = 1){
    setTimeout(async () => {
        logger.log('info',`[${uuid}][${num}]请求地址：${url}`);
        logger.log('info',`[${uuid}][${num}]本次发送：${JSON.stringify(param)}`);
        let result = await sendRequest.post(url,param);
        logger.log('info',`[${uuid}][${num}]请求返回：${result}`);
        if(result !== 'success' && num < 5){
            //进行重发
            await send_post(uuid,url,param,timeout === 0 ? 20000 : timeout * 2,++num)
        }
    }, timeout);
}

/**
 * 发送关闭消息
 * @param {*} uuid 
 * @param {*} param 
 */
const cancel_msg = async(uuid,param) => {
    //因为订阅和消费不能用同一个链接，所以新建一个链接
    param['uuid'] = uuid;
    logger.info(`[${uuid}]定时任务关闭,发送订阅消息[${config.timer_close_name}]：${JSON.stringify(param)}`);
    let result = await redisClient.publishAsync(config.timer_close_name,JSON.stringify(param));
    logger.info(`[${uuid}]定时任务关闭,发送订阅消息[${config.timer_close_name}]结果：${result}`);
    return {
        msg: `[${param.id}]定时器关闭成功`,
        data: {}
    }
}

const cancel = async (uuid,param) => {
    let process_id = process.env.NODE_APP_INSTANCE;
    let id = param.id;
    if(timerObj[id] === undefined)
        throw new Error("定时任务不存在");
    let result = await redisClient.hdelAsync(config.redis_key+"_"+process_id,id);
    if(!result) 
        throw new Error("定时任务redis删除失败");
    timerObj[id].cancel();
    // timerObj.splice(id,1);
    delete timerObj[id];
    timerNum--;
    logger.info(`[${uuid}][${id}]定时任务关闭成功,剩余定时任务数量:${timerNum}`);
    return {
        msg: `[${id}]定时器关闭成功`,
        data: {}
    }
}

module.exports = {
    set:set,
    cancel_msg:cancel_msg,
    cancel:cancel,
}